/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.partner.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.RequiredArgsConstructor;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.partner.domain.Partner;
import me.zhengjie.modules.partner.repository.PartnerRepository;
import me.zhengjie.modules.partner.service.PartnerAccountService;
import me.zhengjie.modules.partner.service.PartnerService;
import me.zhengjie.modules.partner.service.dto.PartnerAccountDto;
import me.zhengjie.modules.partner.service.dto.PartnerDto;
import me.zhengjie.modules.partner.service.dto.PartnerQueryCriteria;
import me.zhengjie.modules.partner.service.mapstruct.PartnerMapper;
import me.zhengjie.modules.partner.service.mapstruct.PartnerVoMapper;
import me.zhengjie.modules.partner.service.vo.PartnerVo;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @website https://el-admin.vip
 * @description 服务实现
 * @author jianyongjie@126.com
 * @date 2021-08-02
 **/
@Service
@RequiredArgsConstructor
public class PartnerServiceImpl implements PartnerService {

    private final PartnerRepository partnerRepository;
    private final PartnerMapper partnerMapper;
    private final PartnerVoMapper partnerVoMapper;
    private final PartnerAccountService partnerAccountService;

    @Override
    public Map<String, Object> queryAll(PartnerQueryCriteria criteria, Pageable pageable) {
        Page<Partner> page = partnerRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        final List<Partner> content = page.getContent();
        if (CollectionUtil.isNotEmpty(content)) {
            content.forEach(x -> {
                final PartnerAccountDto byAdminAccount = partnerAccountService.findByAdminAccount(x.getId());
                if (byAdminAccount != null) {
                    x.setAccount(byAdminAccount.getUsername());
                }
            });
        }
        return PageUtil.toPage(page.map(partnerMapper::toDto));
    }

    @Override
    public List<PartnerDto> queryAll(PartnerQueryCriteria criteria) {
        return partnerMapper.toDto(partnerRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public PartnerDto findById(Long id) {
        Partner partner = partnerRepository.findById(id).orElseGet(Partner::new);
        if (partner == null) {
            return null;
        }
        return partnerMapper.toDto(partner);
    }

    /**
     * 创建商户（默认创建管理员）
     * @param partnerVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Long create(PartnerVo partnerVo) {
        final Partner transform = partnerVoMapper.transform(partnerVo);
        transform.setId(IdWorker.getId());
        transform.setAppSecret(IdWorker.get32UUID());
        partnerRepository.save(transform);

        //创建默认管理员
        partnerAccountService.createAccount(transform.getId(), partnerVo.getAccount(), partnerVo.getPhone());
        return transform.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PartnerVo resources) {
        Partner partner = partnerRepository.findById(resources.getId()).get();
        if (partner == null) {
            throw new BadRequestException("未查询到商户信息");
        }
        partner.setName(resources.getName());
        partner.setCompanyName(resources.getCompanyName());
        partner.setPhone(resources.getPhone());
        partner.setRemark(resources.getRemark());
        partnerRepository.save(partner);

        partnerAccountService.updateAccount(partner.getId(), resources.getAccount(), resources.getPhone());
    }

    @Override
    public PartnerDto findPartnerAndAccountsDetail(Long partnerId) {
        final PartnerDto partnerDto = findById(partnerId);
        final List<PartnerAccountDto> partnerAccountDtos = partnerAccountService.findListByPartnerId(partnerId);
        if (CollectionUtil.isNotEmpty(partnerAccountDtos)) {
            final PartnerAccountDto partnerAccountDto = partnerAccountDtos.stream().filter(x -> x.getSuperAdmin()).findFirst().orElseGet(PartnerAccountDto::new);
            //取管理员账号
            partnerDto.setAccount(partnerAccountDto.getUsername());
            //商户下账号集合
            partnerDto.setAccounts(partnerAccountDtos);
        }
        return partnerDto;
    }

    @Override
    public void download(List<PartnerDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartnerDto partner : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("商户名称", partner.getName());
            map.put("商户公司名称", partner.getCompanyName());
            map.put("联系方式", partner.getPhone());
            map.put("企业地址", partner.getAddress());
            map.put("是否启用", partner.getEnable());
            map.put("备注", partner.getRemark());
            map.put("创建者", partner.getCreateBy());
            map.put("更新者", partner.getUpdateBy());
            map.put("创建日期", partner.getCreateTime());
            map.put("更新时间", partner.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}